home *** CD-ROM | disk | FTP | other *** search
/ BMUG Revelations / BMUG Revelations.toast / Utilities / Random / Commodore 64c / SOURCE / Processor.c < prev    next >
Text File  |  1994-03-19  |  5KB  |  213 lines

  1. /*
  2.     Commodore 64 Emulator v0.1      Earle F. Philhower III 
  3.     Copyright (C) 1993-4            (st916w9r@dunx1.ocs.drexel.edu)
  4.  
  5.     This program is free software; you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation; either version 2 of the License, or
  8.     (at your option) any later version.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program; if not, write to the Free Software
  17.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19. #include "Vectors.h"
  20. #include "Flags.h"
  21. #include "Registers.h"
  22. #include "Memory.h"
  23. #include "Modes.h"
  24. #include "Stack.h"
  25. #include "Keyboard.h"
  26. #include <AppleEvents.h>
  27.  
  28. extern WindowPtr VICWind;
  29. extern Cursor commie;
  30. extern void (* instruct[256]) ();
  31. extern byte cycletime[256];
  32. extern int missingROM;
  33.  
  34. #define    kWindowStrings 500
  35. enum { kRunningWindow=1, kSuspendedWindow };
  36.  
  37. byte interruptProcessor;
  38. static byte numLeftSameChar;
  39. static void ProcessPerLine(void);
  40. extern void ProcessorLoop(void);
  41.  
  42. void ProcessorLoop()
  43. {
  44.     int scanLines, vicCalls;
  45.     byte instructCode, oldMemoryMap, processorCycles, col;
  46.     byte *dc01, *dc00, *d012, *d011, *d018;
  47.     Str255 str;
  48.     unsigned long tempa1, tempa2, tempd1, tempd2;
  49.     byte **localMemory;
  50.     
  51.     /* Set up window, cursor for running state */
  52.     GetIndString(str, kWindowStrings, kRunningWindow);
  53.     SetWTitle(VICWind, str);
  54.     SetCursor(&commie);
  55.     ObscureCursor();
  56.     
  57.     /* Initialize precomputed addresses (minimal speed gain) */
  58.     dc00=&RAM[0xdc00];
  59.     dc01=&RAM[0xdc01];
  60.     d012=&RAM[0xd012];
  61.     d011=&RAM[0xd011];
  62.     d018=&RAM[0xd018];
  63.  
  64.     /* Set up the memory dereferences, and store current map */
  65.     oldMemoryMap=*RAMp1;
  66.     SetUpMemoryMap();
  67.     
  68.     /* Some flags and counters necessray to be initialized */
  69.     interruptProcessor=0;
  70.     numLeftSameChar=0;
  71.     processorCycles=0;
  72.     scanLines=0;
  73.     vicCalls=0;
  74.     
  75.     while (interruptProcessor==0) {
  76.         tempd2=pc;
  77.         asm {
  78.             move.l a1, tempa1
  79.             move.l d1, tempd1
  80.             move.l tempd2, d1
  81.             
  82.             move.l memory, a1
  83.             lsl.l #2, d1
  84.             move.l (a1, d1.l), a1
  85.             move.b (a1), instructCode
  86.             
  87.             move.l tempd1, d1
  88.             move.l tempa1, a1
  89.         };
  90.         
  91.         /*instructCode = ImmediateByte();*/ pc++;
  92.         processorCycles += cycletime[instructCode];
  93.         (*instruct[instructCode])();
  94.  
  95.         /* Set up the memory map if it has changed */
  96.         if (*RAMp1!=oldMemoryMap) {
  97.             SetUpMemoryMap();
  98.             oldMemoryMap=*RAMp1; }
  99.  
  100.         /* If we've done 35 cycles, we've gone through 1 scanline */
  101.         if (processorCycles>35) {
  102.             processorCycles=0;
  103.  
  104.             /* Update the current VIC scan register */
  105.             if (++*d012==0) *d011 ^= 128;
  106.             *d018 |=1;
  107.  
  108.             /* If we've gone through 350 lines, we've due for an interrupt */
  109.             if (++scanLines>350) {
  110.                 scanLines=0;
  111.             
  112.                 /* Set raster to 0 line */
  113.                 *d012=0;
  114.                 *d011&=127;
  115.             
  116.                 /* Currently we just update the keyboard registers */
  117.                 ProcessPerLine();
  118.                 if (++vicCalls==2) {
  119.                     RedrawVIC();
  120.                     vicCalls=0; }
  121.                 
  122.                 /* Call interrupt routine if interrupts enabled */
  123.                 if ((flags&INT)==0) {
  124.                     PushWord(pc);
  125.                     Push(flags);
  126.                     pc=WordAt(IrqTo);
  127.                     }
  128.                 }
  129.             }
  130.         
  131.         /* Set up the keyboard register according to precomputed values */
  132.         *dc01=scanCode[*dc00];
  133.         }
  134.     
  135.     /* Done processing, reset window, cursor */
  136.     RedrawVIC();
  137.     SetCursor(&qd.arrow);
  138.     GetIndString(str, kWindowStrings, kSuspendedWindow);
  139.     SetWTitle(VICWind, str);
  140. }
  141.  
  142. /* Called once per scanline, currently check for keypress or mouse button */ 
  143. static void ProcessPerLine()
  144. {
  145.     EventRecord evt;
  146.     int x;
  147.     char theChar;
  148.     
  149.     /* We keep the same keyboard map for 1/30th of a second */
  150.     if (numLeftSameChar==0) {
  151.         numLeftSameChar=2;
  152.         
  153.         /* Check for any key or mouse press */
  154.         if (GetNextEvent(-1, &evt)!=false)
  155.             switch(evt.what) {
  156.                 /* A mouseclick stops our simulation */
  157.                 case mouseDown:    MiniHandleMouseDown(evt); break;
  158.                 case updateEvt:
  159.                     BeginUpdate((WindowPtr)evt.message);
  160.                     EndUpdate((WindowPtr)evt.message); break;
  161.                 case app4Evt:
  162.                     if (evt.message&1);
  163.                     else interruptProcessor=1;
  164.                     break;
  165.                 case kHighLevelEvent :
  166.                     AEProcessAppleEvent(&evt); break;
  167.                 /* A keypress is simulated by fudging the CIA registers */
  168.                 case keyDown:    case autoKey:
  169.                     theChar = evt.message&charCodeMask;
  170.                     if ((evt.modifiers&cmdKey)!=0)
  171.                         DoMenuChoice(MenuKey(theChar));
  172.                     else {
  173.                     AppleScanKeyboard(evt.message&charCodeMask, evt.modifiers);
  174.                     SetupScanCodes();}
  175.                     }
  176.         
  177.         /* No keypress, so clear out keyboard register fudge */
  178.         else { for (x=0; x<256; x++) scanCode[x]=0xff; SystemTask(); }
  179.         }
  180.     else numLeftSameChar--;
  181. }
  182.  
  183. #define ALIGNBYTE
  184.  
  185. MiniHandleMouseDown(event)
  186. EventRecord event;
  187. {
  188.     WindowPtr theWind;
  189.     GrafPtr gp;
  190.     Point x;
  191.     short thePart;
  192.     extern Rect dragRect;
  193.     
  194.     thePart=FindWindow(event.where, &theWind);
  195.     switch(thePart) {
  196.         case inSysWindow: SystemClick(&event, theWind); interruptProcessor=1; break;
  197.         case inDrag:
  198.             DragWindow(theWind, event.where, &dragRect);
  199. #ifdef ALIGNBYTE
  200.             GetPort(&gp);
  201.             SetPort(theWind);
  202.             x.h=x.v=0;
  203.             LocalToGlobal(&x);
  204.             x.h&=0xfff8;
  205.             MoveWindow(theWind, x.h, x.v, TRUE);
  206.             SetPort(gp);
  207. #endif
  208.             break;
  209.         case inMenuBar: DoMenuChoice(MenuSelect(event.where)); break;
  210.         case inContent: interruptProcessor=1; break;
  211.         }
  212. }
  213.